"""
日志配置 - Windows兼容版本，彻底解决文件锁定问题
"""

import sys
import os
import time
import threading
from pathlib import Path
from loguru import logger
from app.core.config import settings

# 移除默认处理器
logger.remove()

# 添加控制台输出
logger.add(
    sys.stdout,
    format="<green>{time:YYYY-MM-DD HH:mm:ss}</green> | <level>{level: <8}</level> | <cyan>{name}</cyan>:<cyan>{function}</cyan>:<cyan>{line}</cyan> - <level>{message}</level>",
    level=settings.LOG_LEVEL,
    colorize=True,
    catch=True  # 捕获异常避免程序崩溃
)

# 全局日志锁，防止多进程冲突
_log_lock = threading.Lock()
_log_initialized = False

def _safe_add_file_handler():
    """安全地添加文件处理器，避免多进程冲突"""
    global _log_initialized

    with _log_lock:
        if _log_initialized:
            return True

        try:
            log_dir = Path(settings.LOG_FILE).parent
            log_dir.mkdir(parents=True, exist_ok=True)

            # 检查文件是否被其他进程占用
            log_file_path = Path(settings.LOG_FILE)
            if log_file_path.exists():
                try:
                    # 尝试以独占模式打开文件检查是否被占用
                    with open(log_file_path, 'a', encoding='utf-8') as f:
                        pass
                except (PermissionError, OSError) as e:
                    # 文件被占用，使用带时间戳的文件名
                    timestamp = int(time.time())
                    log_file_path = log_file_path.parent / f"app_{timestamp}.log"
                    print(f"原日志文件被占用，使用新文件: {log_file_path}")

            # Windows特殊处理：禁用轮转，使用单一大文件
            if sys.platform.startswith('win'):
                logger.add(
                    str(log_file_path),
                    format="{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {name}:{function}:{line} - {message}",
                    level=settings.LOG_LEVEL,
                    rotation=None,  # 禁用轮转避免文件锁定
                    retention=None,  # 禁用自动清理
                    compression=None,  # 禁用压缩
                    enqueue=True,  # 使用队列避免阻塞
                    serialize=False,  # 禁用序列化
                    backtrace=False,  # 禁用backtrace
                    diagnose=False,  # 禁用diagnose
                    buffering=1,  # 行缓冲
                    encoding="utf-8",
                    delay=True,  # 延迟创建文件
                    catch=True,  # 捕获错误
                )
                _log_initialized = True
                logger.info("Windows日志系统初始化成功（无轮转模式）")
                return True
            else:
                # 非Windows系统使用标准配置
                logger.add(
                    str(log_file_path),
                    format="{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {name}:{function}:{line} - {message}",
                    level=settings.LOG_LEVEL,
                    rotation="10 MB",
                    retention="30 days",
                    compression="zip",
                    enqueue=True,
                    serialize=False,
                    backtrace=True,
                    diagnose=True,
                    buffering=1,
                    encoding="utf-8",
                    delay=True,
                )
                _log_initialized = True
                logger.info("标准日志系统初始化成功")
                return True

        except Exception as e:
            print(f"文件日志初始化失败: {e}")
            logger.warning("文件日志初始化失败，仅使用控制台输出")
            return False

# 初始化文件日志
file_log_success = _safe_add_file_handler()


# 添加异常处理钩子
def handle_exception(exc_type, exc_value, exc_traceback):
    """全局异常处理"""
    if issubclass(exc_type, KeyboardInterrupt):
        sys.__excepthook__(exc_type, exc_value, exc_traceback)
        return

    # 避免traceback序列化问题，只记录异常信息
    try:
        import traceback
        tb_str = ''.join(traceback.format_exception(exc_type, exc_value, exc_traceback))
        logger.critical(f"未捕获的异常: {exc_type.__name__}: {exc_value}\n{tb_str}")
    except Exception:
        # 如果格式化失败，至少记录基本信息
        logger.critical(f"未捕获的异常: {exc_type.__name__}: {exc_value}")

# 设置全局异常处理器
sys.excepthook = handle_exception

# 导出logger和状态信息
__all__ = ["logger", "file_log_success"]
